/* 
 * Cashbox is the legal property of its developers, whose names are listed in the copyright file included
 * with this source distribution.
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program; if not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#import <Cashbox/CBAccount.h>
#import <Cashbox/CBDataControllerProtocol.h>
#import <Cashbox/CBChartItem.h>
#import "CBPieViewController.h"
#import "CBBaseReport.h"

void *CBReportChangeContext = @"CBReportChangeContext";

@interface CBPieViewController (PRIVATE)
- (void)setupChart;
@end

@implementation CBPieViewController

+ (NSString *)nibName {
	return @"Pie";
}

- (void)dealloc {
	[report release];
	[super dealloc];
}

- (void)viewWillActivate {
	[self addObserver:self forKeyPath:@"report" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.account" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.startDate" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.startDateType" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.endDate" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.endDateType" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.transactionType" options:0 context:CBReportChangeContext];
	[self addObserver:self forKeyPath:@"reportController.selection.includeUnlabeled" options:0 context:CBReportChangeContext];
}

- (void)viewDidInactivate {
	[self removeObserver:self forKeyPath:@"report"];
	[self removeObserver:self forKeyPath:@"reportController.selection.account"];
	[self removeObserver:self forKeyPath:@"reportController.selection.startDate"];
	[self removeObserver:self forKeyPath:@"reportController.selection.startDateType"];
	[self removeObserver:self forKeyPath:@"reportController.selection.endDate"];
	[self removeObserver:self forKeyPath:@"reportController.selection.endDateType"];
	[self removeObserver:self forKeyPath:@"reportController.selection.transactionType"];
	[self removeObserver:self forKeyPath:@"reportController.selection.includeUnlabeled"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
					  ofObject:(id)object
						change:(NSDictionary *)change
					   context:(void *)context {
	if (context == CBReportChangeContext) {
		[self setupChart];
	}
}

- (void)awakeFromNib {
	[topView setDrawsBackground:YES];
	[topView setBackgroundColor:[NSColor whiteColor]];
	
	[bottomView setDrawsBackground:YES];
	[bottomView setBackgroundColor:[NSColor colorWithCalibratedWhite:0.88 alpha:1]];
	[bottomView setDrawsBorder:YES];
	[bottomView setBorderColor:[NSColor colorWithCalibratedWhite:0.65 alpha:1]];
	
	[accountsController setManagedObjectContext:[[cashbox dataController] managedObjectContext]];
	[accountsController setEntityName:[CBAccount entityName]];
	[accountsController setSortDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)] autorelease]]];
	[accountsController fetchWithRequest:nil merge:NO error:NULL];
}

- (void)setupChart {
	if (!settingUpChart && [self report]) {
		settingUpChart = TRUE;
		[reportController setContent:[self report]];
		
		NSFetchRequest *request = [[NSFetchRequest alloc] init];
		NSValueTransformer *transformer = [NSValueTransformer valueTransformerForName:@"CBIntFloatTransformer"];
		[request setEntity:[CBTransaction entity]];
		[request setPredicate:[NSPredicate predicateWithFormat:@"account = %@ OR %@ = NULL", [report account], [report account]]];
		NSArray *results = [[[cashbox dataController] managedObjectContext] executeFetchRequest:request error:nil];
		
		NSDate *start = [NSDate date];
		CBRoleType role;
		if ([report transactionType] == CBWithdrawalType) { role = CBNegativeCashflowRole; }
		if ([report transactionType] == CBDepositType) { role = CBPositiveCashflowRole; }
		
		NSMutableDictionary *slices = [NSMutableDictionary dictionary];
		for (CBTransaction *transaction in results) {
			double amount = [[transformer transformedValue:[transaction valueForRoleType:role]] doubleValue];
			if (amount >= 0) {
				CBLabel *label = [transaction label];
				if (label || [report includeUnlabeled]) {
					NSString *name = [label name];
					NSString *key = [NSString stringWithFormat:@"%05i_%@", [label index], name];
					CBChartItem *slice = [slices objectForKey:key];
					if (!slice) {
						slice = [CBChartItem chartItemWithLabel:name ? name : FSLocalizedString(@"No Label", nil)
															  color:[[label color] darkenAndAdjustSaturationBy:0.1]
															 weight:0];
						[slices setObject:slice forKey:key];
					}
					
					[slice setWeight:[slice weight] + amount];				
				}
			}
		}
		NSLog(@"calculation took %f", [[NSDate date] timeIntervalSinceDate:start]);

		NSMutableArray *orderedSlices = [NSMutableArray array];
		for (NSString *key in [[slices allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
			[orderedSlices addObject:[slices objectForKey:key]];
		}
		
		[pieChart setObjectValue:orderedSlices];
		settingUpChart = FALSE;
	} else {
		[pieChart setObjectValue:nil];
	}
							  
}


#pragma mark properties
// ----------------------------------------------------------------------------------------------------
// properties
// ----------------------------------------------------------------------------------------------------

@synthesize report;


#pragma mark autosavename
// ----------------------------------------------------------------------------------------------------
// autosavename
// ----------------------------------------------------------------------------------------------------

- (void)setAutosaveName:(NSString *)name {
	// nothing to save
}

- (NSString *)autosaveName {
	// nothing saved
	return nil;
}


@end
